/*
 * Copyright (c) 2025 粤港澳大湾区（广东）国创中心
 *
 * This file is a part of NctiCAEPre.
 *
 * NctiCAEPre is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 *
 */

#include "NctiQTPubFun.h"

#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>

#include <QDir>
#include <QCoreApplication>

#include "NctiRenderManager.h"
#include "NctiPluginsManager.h"
#include "NctiSystemParams.h"

namespace NCTI {
    
    // 系统配置-设置布尔类型参数
    static void setBoolParam(const QJsonObject& obj, const QString& key, const std::function<void(bool)>& setter)
    {
        if (obj.contains(key)) { setter(obj.value(key).toBool()); }
    }

    // 系统配置-设置颜色类型参数
    static void setColorParam(const QJsonObject& obj,
        const QString& key,
        const std::function<void(const ParamsColor&)>& setter)
    {
        if (obj.contains(key)) {
            QColor color(obj.value(key).toString());
            setter(ParamsColor(color.red(), color.green(), color.blue()));
        }
    }

    // 系统配置-设置背景渐变色
    static void setBackgroundColors(const QJsonValue& bgColorValue, NctiSystemParams* pSystemParams)
    {
        QColor topColor(5, 38, 79);
        QColor bottomColor(81, 90, 146);

        if (bgColorValue.isArray()) {
            QJsonArray bgColorArray = bgColorValue.toArray();
            if (bgColorArray.size() == 2) {
                topColor = QColor(bgColorArray.at(0).toString());
                bottomColor = QColor(bgColorArray.at(1).toString());
            }
        }

        pSystemParams->SetTopColor(ParamsColor(topColor.red(), topColor.green(), topColor.blue()));
        pSystemParams->SetBottomColor(ParamsColor(bottomColor.red(), bottomColor.green(), bottomColor.blue()));
    }

    // 系统配置-设置模型相关颜色
    static void setModelColors(const QJsonObject& windowsObject, NctiSystemParams* pSystemParams)
    {
        if (windowsObject.contains("HighlightColor"))
        {
            QColor highlightColor = windowsObject.value("HighlightColor").toString();
            pSystemParams->SetHighlightColor(ParamsColor(highlightColor.red(), highlightColor.green(), highlightColor.blue()));
        }
        if (windowsObject.contains("FaceColor")) { 
            QColor faceColor = windowsObject.value("FaceColor").toString();
            pSystemParams->SetFaceColor(ParamsColor(faceColor.red(), faceColor.green(), faceColor.blue()));
        }
        if (windowsObject.contains("EdgeColor")) {
            QColor edgeColor = windowsObject.value("EdgeColor").toString();
            pSystemParams->SetLineColor(ParamsColor(edgeColor.red(), edgeColor.green(), edgeColor.blue()));
        }
        if (windowsObject.contains("VertexColor")) { 
            QColor vertexColor = windowsObject.value("VertexColor").toString();
            pSystemParams->SetVertexColor(ParamsColor(vertexColor.red(), vertexColor.green(), vertexColor.blue()));
        }
        if (windowsObject.contains("BackColor")) {
            QColor vertexColor = windowsObject.value("BackColor").toString();
            pSystemParams->SetBackColor(ParamsColor(vertexColor.red(), vertexColor.green(), vertexColor.blue()));
        }
        if (windowsObject.contains("ContourColor")) {
            QColor vertexColor = windowsObject.value("ContourColor").toString();
            pSystemParams->SetContourColor(ParamsColor(vertexColor.red(), vertexColor.green(), vertexColor.blue()));
        }
        if (windowsObject.contains("ShowBackColor")) {
            bool vertexColor = windowsObject.value("ShowBackColor").toBool();
            pSystemParams->SetShowBackColor(vertexColor);
        }
        if (windowsObject.contains("ShowContour")) {
            bool vertexColor = windowsObject.value("ShowContour").toBool();
            pSystemParams->SetShowContour(vertexColor);
        }

        if (windowsObject.contains("LineType")) {
            pSystemParams->SetLineType(windowsObject.value("LineType").toInt());
        }

        if (windowsObject.contains("LineWidth")) {
            Ncti_Double dLineWidth = windowsObject.value("LineWidth").toDouble();
            pSystemParams->SetLineWidth(dLineWidth);
        }
    }

    // 系统配置-设置草图相关颜色
    static void setSketchColors(const QJsonObject& windowsObject, NctiSystemParams* pSystemParams)
    {
        // 默认颜色
        QColor lineSegmentColor("#FFFFFF");
        QColor dimensionLineColor("#1EB341");
        QColor gridLineColor("#4D5D80");

        // 从配置获取颜色
        if (windowsObject.contains("LineSegmentColor")) {
            lineSegmentColor = windowsObject.value("LineSegmentColor").toString();
        }
        if (windowsObject.contains("DimensionLineColor")) {
            dimensionLineColor = windowsObject.value("DimensionLineColor").toString();
        }
        if (windowsObject.contains("GridLineColor")) { gridLineColor = windowsObject.value("GridLineColor").toString(); }

        // 设置[线段/尺寸线/网格线]颜色
        pSystemParams->SetLineSegmentColor(
            ParamsColor(lineSegmentColor.red(), lineSegmentColor.green(), lineSegmentColor.blue()));
        pSystemParams->SetDimensionLineColor(
            ParamsColor(dimensionLineColor.red(), dimensionLineColor.green(), dimensionLineColor.blue()));
        pSystemParams->SetGridLineColor(ParamsColor(gridLineColor.red(), gridLineColor.green(), gridLineColor.blue()));
    }

    // 系统配置-设置自动保存路径
    static void setAutoSaveConfig(const QJsonObject& windowsObject, NctiSystemParams* pSystemParams)
    {
        bool openState = false;
        int time = 300;

        if (windowsObject.contains("AutoSaveValid")) { openState = windowsObject.value("AutoSaveValid").toBool(); }
        if (windowsObject.contains("AutoSaveTime")) { time = windowsObject.value("AutoSaveTime").toInt(); }
        if (windowsObject.contains("AutoSaveFolder")) {
            QString qSaveFilePath = windowsObject.value("AutoSaveFolder").toString();
            QByteArray byte = qSaveFilePath.toUtf8();
            pSystemParams->SetAutoSaveFolder(byte.data());
        }

        // 如果未设置备份路径，使用临时路径
        if (pSystemParams->GetAutoSaveFolder().size() < 1) {
            QDir tempDir(QDir::tempPath());
            QString tempPath = tempDir.filePath("NCTI");
            QByteArray byte = tempPath.toUtf8();
            pSystemParams->SetAutoSaveFolder(byte.data());
        }

        pSystemParams->SetAutoSaveValid(openState);
        pSystemParams->SetAutoSaveTime(time);
    }

    // 加载渲染器配置
    static void loadRendererConfig(const QJsonObject& renderObject, NctiSystemParams* pSystemParams)
    {
        if (renderObject.contains("BackgroundColor")) {
            setBackgroundColors(renderObject.value("BackgroundColor"), pSystemParams);
        }

        setBoolParam(renderObject, "OpenDebugInfo", [](bool value) {
                NctiRenderManager::instance()->GetOpenDebugInfo() = value;
            });

        setBoolParam(renderObject, "InputDebugInfoToFile", [](bool value) {
            NctiRenderManager::instance()->GetInputDebugInfoToFile() = value;
            });

        setBoolParam(renderObject, "InputDebugInfoToCommand", [](bool value) {
            NctiRenderManager::instance()->GetInputDebugInfoToCommand() = value;
            });

        setBoolParam(
            renderObject, "OpenCalTime", [](bool value) {
                NctiRenderManager::instance()->GetOpenCalTime() = value;
            });

        setBoolParam(renderObject, "RenderPreHighlight", [](bool value) {
            NctiRenderManager::instance()->GetPreHighLight() = value;
            });

        setBoolParam(renderObject, "RenderBoxSelctAll", [](bool value) {
            NctiRenderManager::instance()->GetBoxSelctAll() = value;
            });

        if (renderObject.contains("ObjectDisplayMode")) {
            QJsonArray displayModeArray = renderObject.value("ObjectDisplayMode").toArray();
            if (displayModeArray.size() >= 3) {
                pSystemParams->SetFaceState(displayModeArray.at(0).toBool());
                pSystemParams->SetEdgeState(displayModeArray.at(1).toBool());
                pSystemParams->SetVertexState(displayModeArray.at(2).toBool());
            }
        }

        setBoolParam(renderObject, "OperatingAxis", [pSystemParams](bool value) { 
            pSystemParams->SetOperatingAxis(value); 
            });

        setBoolParam(renderObject, "OpenRenderDisplayTime", [pSystemParams](bool value) {
            pSystemParams->SetOpenRenderDisplayTime(value);
            });
    }

    // 加载窗口配置
    static void loadWindowsConfig(const QJsonObject& windowsObject, NctiSystemParams* pSystemParams)
    {
        // 主题颜色
        if (windowsObject.contains("ThemeColor")) {
            QString themeColor = windowsObject.value("ThemeColor").toString();
            pSystemParams->SetThemeColor(themeColor == "dark" ? 0 : 1);
        }

        // 语言
        if (windowsObject.contains("Language")) {
            QString language = windowsObject.value("Language").toString();
            pSystemParams->SetLanguage(language == "chinese" ? 0 : 1);
        }

        // 模型相关颜色
        setModelColors(windowsObject, pSystemParams);

        // 草图绘制相关颜色
        setSketchColors(windowsObject, pSystemParams);

        // UI组件显示状态
        setBoolParam(windowsObject, "Console", [pSystemParams](bool value) { pSystemParams->SetConsole(value); });

        setBoolParam(windowsObject, "ScriptEditor", [pSystemParams](bool value) { pSystemParams->SetScriptEditor(value); });

        // 自动保存配置
        setAutoSaveConfig(windowsObject, pSystemParams);
    }

    void NctiQTPubFun::LoadingSystemParams()
    {
        QString executablePath = QCoreApplication::applicationFilePath();
        QFileInfo fileInfo(executablePath);

        QString configFile = QString::fromUtf8(NctiPluginsManager::instance()->GetConfigurationFile());
        QString configFilePath = QString("%1/%2").arg(fileInfo.absolutePath(), configFile);

        QFile file(configFilePath);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { return; }

        NctiSystemParams* pSystemParams = NctiSystemParams::instance();
        QByteArray fileData = file.readAll();
        QJsonDocument jsonDoc = QJsonDocument::fromJson(fileData);
        QJsonObject jsonObject = jsonDoc.object();

        // 渲染器配置
        if (jsonObject.contains("Renderer")) { loadRendererConfig(jsonObject["Renderer"].toObject(), pSystemParams); }

        // 窗口配置
        if (jsonObject.contains("Windows")) { loadWindowsConfig(jsonObject["Windows"].toObject(), pSystemParams); }
    }


}